package com.mercury.core.aop.aspect;

import com.alibaba.fastjson.JSON;
import com.mercury.core.manager.RedisManager;
import com.mercury.core.result.ResultVo;
import com.mercury.core.aop.annotation.AccessRestrictionLimit;
import lombok.SneakyThrows;
import org.springframework.lang.NonNull;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * @author mercury
 **/
public class AccessRestrictionLimitInterceptor implements HandlerInterceptor {

    @Resource
    private RedisManager redisManager;

    @SneakyThrows
    @Override
    public boolean preHandle(@NonNull HttpServletRequest request,
                             @NonNull HttpServletResponse response,
                             @NonNull Object handler) {
        //判断请求是否是属于方法的请求
        if (handler instanceof HandlerMethod) {
            HandlerMethod hm = (HandlerMethod) handler;
            //获取方法上的注解，看是否有该注解
            AccessRestrictionLimit accessLimit = hm.getMethodAnnotation(AccessRestrictionLimit.class);
            if (null == accessLimit) {
                //没有直接返回true
                return true;
            }
            int limit = accessLimit.limit();
            long seconds = accessLimit.seconds();
            String ip = request.getRemoteAddr();
            //存放在redis中的key
            String key = request.getServletPath() + ":" + ip;
            if (!redisManager.hasKey(key)) {
                // 第一次访问,设置过期时间
                redisManager.set(key, 1, seconds, TimeUnit.SECONDS);
                return true;
            }
            Optional<String> optionalS = redisManager.get(key);
            if (optionalS.isPresent()) {
                int count = Integer.parseInt(optionalS.get());
                if (count < limit) {
                    ++count;
                    redisManager.set(key, count, seconds, TimeUnit.SECONDS);
                    return true;
                }
            }
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json; charset=utf-8");
            response.getWriter().write(JSON.toJSONString(ResultVo.err("操作过于频繁,请稍后再试！")));
            return false;
        }
        return true;
    }

}
